/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.service;

import br.com.foxline.enums.PaymentType;
import br.com.foxline.enums.Reports;
import br.com.foxline.enums.StatusSale;
import br.com.foxline.enums.TypeAddress;
import br.com.foxline.model.*;
import br.com.foxline.util.Caracter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author ely
 */
@Stateless
public class SaleService extends GenericService<Sale> {

    public SaleService() {
        super(Sale.class);
    }
    @EJB
    private UserService userService;
    @EJB
    private GroupService groupService;
    @EJB
    private SaleService saleService;
    @EJB
    private EnterpriseService enterpriseService;
    @EJB
    private CustomerService customerService;

    @Override
    public void save(Sale s) {
        s.setCpfOfTheWitness1(Caracter.removecaracter(s.getCpfOfTheWitness1()));
        s.setCpfOfTheWitness2(Caracter.removecaracter(s.getCpfOfTheWitness2()));
        s.setPhoneOfReference1(Caracter.removecaracter(s.getPhoneOfReference1()));
        s.setPhoneOfReference2(Caracter.removecaracter(s.getPhoneOfReference2()));
        super.save(s);
    }

    public List<Sale> findSale(Enterprise enterprise, Integer block, Integer lot, Customer customer, StatusSale status, Date dateSale) {
        List<Sale> lista = new ArrayList<Sale>();
        System.out.println("Chegou " + enterprise);
        try {
            String sql = "Select s from Sale s JOIN s.enterprise e JOIN s.customer c JOIN s.corrector co where ";
            if (enterprise != null && (enterprise.getId() != null)) {
                sql += "e.id=:eid AND ";
            }
            if (block != null) {
                sql += "s.lot.block=:block AND ";
            }
            if (lot != null) {
                sql += "s.lot.num=:lot AND ";
            }
            if (customer != null && (customer.getId() != null)) {
                sql += "c.id=:cid AND ";
            }
            if (status != null) {
                sql += "s.statusSale=:status AND ";
            }
            if (dateSale != null) {
                sql += "d.saleDate=:saleDate AND ";
            }
            Users user = userService.getCurrentUserFull();

            if (!user.getGroups().contains(groupService.findGroupByName("Administrador"))) {
                sql += " (e.admin.id=:uid OR co.user.id=:uid) AND ";
            }

            sql += "1=1";

            Query query = getEntityManager().createQuery(sql).setMaxResults(50);
            if (!user.getGroups().contains(groupService.findGroupByName("Administrador"))) {
                query.setParameter("uid", user.getId());
            }
            if (enterprise != null && (enterprise.getId() != null)) {
                query.setParameter("eid", enterprise.getId());
            }
            if (block != null) {
                query.setParameter("block", block.toString());
            }
            if (lot != null) {
                query.setParameter("lot", lot);
            }
            if (customer != null && (customer.getId() != null)) {
                query.setParameter("cid", customer.getId());
            }
            if (status != null) {
                query.setParameter("status", status);
            }
            if (dateSale != null) {
                query.setParameter("saleDate", dateSale);
            }
            lista = query.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lista;
    }

    public void reportsContract(Sale sale) {
        HashMap<String, Object> parametros;
        sale = find(sale.getId());
        parametros = new HashMap<String, Object>();
        parametros.put("text", "JUHGHSADFVHSGJSGDFSDGSDSDSDJGFSDJ");

        sale.setEnterprise(enterpriseService.find(sale.getEnterprise().getId()));

        parametros.put("text", "" + sale.getEnterprise().getName());
        parametros.put("NAME_CONSTRUCTION", "" + sale.getEnterprise().getConstruction().getName());
        parametros.put("CNPJ_CONSTRUCTION", "" + sale.getEnterprise().getConstruction().getCnpj());

        try {
            if (sale.getEnterprise().getConstruction() != null && sale.getEnterprise().getConstruction().getAddress() != null) {
                parametros.put("CITY_CONSTRUCTION", ""
                        + sale.getEnterprise().getConstruction().getAddress().getCity() != null
                        ? sale.getEnterprise().getConstruction().getAddress().getCity().getName() : "");

                parametros.put("END_CONSTRUCTION", ""
                        + sale.getEnterprise().getConstruction().getAddress().getPatio() + ", "
                        + sale.getEnterprise().getConstruction().getAddress().getNum() + ", Bairro "
                        + sale.getEnterprise().getConstruction().getAddress().getDistrict());

                parametros.put("CEP_CONSTRUCTION", "" + sale.getEnterprise().getConstruction().getAddress().getCep());
            }
        } catch (Exception e) {
        }
        String text = "";
        try {
            if (!sale.getEnterprise().getConstruction().getCustumers().isEmpty()) {
                if (sale.getEnterprise().getConstruction().getCustumers().size() > 1) {
                    int cont = 0;
                    for (Customer customer : sale.getEnterprise().getConstruction().getCustumers()) {
                        if (cont >= 1) {
                            text += " ou " + customer.getName();
                        } else {
                            text += customer.getName();
                        }
                        cont++;
                    }
                } else {
                    Customer customer = sale.getEnterprise().getConstruction().getCustumers().get(0);
                    text = "" + customer.getName() + ", portador do CPF " + customer.getCpf();
                }
            }
        } catch (Exception e) {
        }
        try {

            parametros.put("RESPONSIBLE_CONSTRUCTION", "" + text);
            parametros.put("NAME_CUSTOMER", "" + sale.getCustomer().getName() + ", portador do CPF " + sale.getCustomer().getCpf());
            parametros.put("PROMITENTE_COMPRADOR", "" + sale.getCustomer().getName());
            parametros.put("N_LOTE", "" + sale.getLot().getNum());
            parametros.put("NAME_ENTERPRISE", "" + sale.getEnterprise().getName());
            parametros.put("CITY_ENTERPRISE", "" + sale.getEnterprise().getCity().getName());
            parametros.put("VALOR_TOTAL", "" + sale.getTotalValue());
            parametros.put("VALOR_TOTAL_EXTENSO", "");

        } catch (Exception e) {
        }
        if (sale.getPaymentType() != PaymentType.AT_SIGHT) {
            parametros.put("FORM_PAYMENT", "Entrada no valor de R$ " + sale.getEntryValue() + " () , mais "
                    + sale.getQuantityOfParcel() + " de R$ " + sale.getParcelValue() + " ");
        } else {
            parametros.put("FORM_PAYMENT", "Compra à vista no valor de  R$ " + sale.getTotalValue() + " ");
        }


        try {
            parametros.put("INDICE_REAJUSTE", "" + sale.getEnterprise().getAnualCorrection());
            parametros.put("MULTA_INADIPLENCIA", "" + sale.getEnterprise().getPorcInadiplencia());
            parametros.put("JUROS_INADIPLENCIA", "" + sale.getEnterprise().getPorcInadiplencia());
            parametros.put("REG_NOTTARY", "" + sale.getEnterprise().getNumRegistryNotary());
            parametros.put("TEST_NOME1", "" + sale.getNameOfTheWitness1());
            parametros.put("TEST_NOME2", "" + sale.getNameOfTheWitness2());
            parametros.put("TEST_CPF1", "" + sale.getCpfOfTheWitness1());
            parametros.put("TEST_CPF2", "" + sale.getCpfOfTheWitness2());
        } catch (Exception e) {
        }
        ReportService.genReport(parametros, null, Reports.CONTRACT);
    }

    public String format(Date data) {
        if (data != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            return sdf.format(data);
        }
        return "";
    }

    public void reportsProposedContract(Sale sale) {
        HashMap<String, Object> parametros;
        parametros = new HashMap<String, Object>();
        Enterprise enterprise = sale.getEnterprise();
        Customer customer;

        if (enterprise == null) {
            return;
        }
        customer = sale.getCustomer();
        if (customer == null) {
            return;
        }
        parametros.put("CITY_ENTERPRISE", "" + enterprise.getCity() != null ? enterprise.getCity().getName() : "");
        parametros.put("CUSTOMER_NAME", "" + customer.getName());
        parametros.put("CUSTOMER_GENDER", "" + customer.getGender().getName());
        parametros.put("CUSTOMER_RG", "" + customer.getRg());
        parametros.put("CUSTOMER_CPF", "" + customer.getCpf());
        parametros.put("CUSTOMER_PROFESSION", "" + customer.getProfession());

        parametros.put("CUSTOMER_DATEOFBIRTH", "" + format(customer.getDateOfBirth()));
        parametros.put("CUSTOMER_FONE", "" + customer.getFixedPhone());
        parametros.put("CUSTOMER_CEL", "" + customer.getCelPhone());
        parametros.put("CUSTOMER_CIVILSTATUS", "" + customer.getCivilStatus().getName());
        parametros.put("CUSTOMER_EMAIL", "" + customer.getEmail());
        try {
            for (Address res : customer.getAddresses()) {
                if (res.getTypeAddress() == TypeAddress.RESIDENCIAL) {
                    parametros.put("ADDRESS_RES", "" + res.getPatio());
                    parametros.put("ADDRESS_RES_NUM", "" + res.getNum());
                    parametros.put("ADDRESS_RES_COMP", "" + res.getComplement());
                    parametros.put("ADDRESS_RES_NEIG", "" + res.getDistrict());
                    parametros.put("ADDRESS_RES_CITY", "" + res.getCity() != null ? res.getCity().getName() : "");
                    parametros.put("ADDRESS_RES_UF", "" + (res.getCity() != null
                            ? res.getCity().getCountry() != null
                            ? res.getCity().getCountry().getSgl() : "" : ""));
                    parametros.put("ADDRESS_RES_ZIPCODE", "" + res.getCep());
                } else if (res.getTypeAddress() == TypeAddress.COBRANÇA) {
                    parametros.put("ADDRESS_CORRES", res.getPatio());
                    parametros.put("ADDRESS_CORRES_NUM", "" + res.getNum());
                    parametros.put("ADDRESS_CORRES_COMPL", "" + res.getComplement());
                    parametros.put("ADDRESS_CORRES_NEIG", "" + res.getDistrict());
                    parametros.put("ADDRESS_CORRES_CITY", "" + (res.getCity() != null ? res.getCity().getName() : ""));
                    parametros.put("ADDRESS_CORRES_UF", "" + (res.getCity() != null
                            ? res.getCity().getCountry() != null
                            ? res.getCity().getCountry().getSgl() : "" : ""));
                    parametros.put("ADDRESS_CORRES_ZIPCODE", "");
                }
            }
        } catch (Exception e) {
        }
        try {
            if (customer.getSpouse() != null) {
                parametros.put("CONJUGE_NAME", "" + customer.getSpouse().getName());
                parametros.put("CONJUGE_CPF", "" + customer.getSpouse().getCpf());
                parametros.put("CONJUGE_RG", "" + customer.getSpouse().getRg());
                parametros.put("CONJUGE_PROFESSION", "" + customer.getSpouse().getProfession());
            }
        } catch (Exception e) {
        }
        parametros.put("REF1_NOME", sale.getNameOfReference1());
        parametros.put("REF1_FONE", sale.getPhoneOfReference1());
        parametros.put("REF2_NOME", sale.getNameOfReference2());
        parametros.put("REF2_FONE", sale.getPhoneOfReference2());

        try {
            if (enterprise != null && sale.getLot() != null) {
                parametros.put("ENTERPRISE", "" + enterprise.getName());
                parametros.put("BLOCK", "" + sale.getLot().getBlock());
                parametros.put("LOT", "" + sale.getLot().getNum());
                parametros.put("ENTERPRISE_CITY", "" + (enterprise.getCity() != null ? enterprise.getCity().getName() : ""));
                parametros.put("ENTERPRISE_UF", "" + (enterprise.getCity() != null
                        ? enterprise.getCity().getCountry() != null
                        ? enterprise.getCity().getCountry().getSgl() : "" : ""));
            }
        } catch (Exception e) {
        }
        try {
            parametros.put("ENTRY_VALUE", "" + sale.getEntryValue());
            parametros.put("DATE_ENTRY", "" + format(sale.getSaleDate()));
            parametros.put("PARC_INTE", "" + sale.getParcelValue());
            parametros.put("PARC_INTE_DATE", "" + format(sale.getFirstParcelDate()));
            parametros.put("VALUE_PARCEL", "" + sale.getParcelValue());
            parametros.put("QTD_PARCEL", "" + sale.getQuantityOfParcel());
            parametros.put("DATE_1_PARCEL", "" + format(sale.getFirstParcelDate()));
            parametros.put("ANUAL_CORRECTION", "" + enterprise.getAnualCorrection());
            parametros.put("HONORARIO", "" + sale.getTotalValue().multiply(new BigDecimal("0.05")));
            parametros.put("HONORARIO_DATE", "" + (sale.getHonorary() != null ? format(sale.getHonorary().getCreatedAt()) : ""));
        } catch (Exception e) {
        }
        ReportService.genReport(parametros, null, Reports.PROPOSED_CONTRACT);
    }

    public boolean verifyIfCanApprove(Sale s) {
        Users u = userService.getCurrentUserFull();
        if (s.getStatusSale().equals(StatusSale.FINALIZED)) {
            return false;
        }
        if (u.getId().equals(enterpriseService.find(s.getEnterprise().getId()).getAdmin().getId())) {
            return true;
        }
        if (u.getGroups().contains(groupService.findGroupByName("Administrador"))) {
            return true;
        }
        return false;
    }

    /**
     * Consulta para gerar o relatório de venda.
     *
     * @param enterprise
     * @param startDate
     * @param endDate
     * @return
     */
    public List<Sale> reportsSales(Enterprise enterprise, Corrector corrector, Date startDate, Date endDate) {
        String sql = "select s from sale s where 1=1";
        if (enterprise != null) {
            sql += " and s.enterprise=:enterprise";
        }
        if (corrector != null) {
            sql += " and s.corrector=:corrector";
        }
        if (startDate != null && endDate != null) {
            sql += " and(s.saleDate BETWEEN :startDate and :endDate)";
        } else if (endDate != null) {
            sql += " and s.saleDate >= :endDate";
        } else if (startDate != null) {
            sql += " and s.saleDate >= :startDate";
        }
        Query query = getEntityManager().createQuery(sql);
        if (enterprise != null) {
            query.setParameter("enterprise", enterprise);
        }
        if (corrector != null) {
            query.setParameter("corrector", corrector);
        }
        if (startDate != null && endDate != null) {
            query.setParameter("startDate", startDate);
            query.setParameter("endDate", endDate);
        } else if (endDate != null) {
            query.setParameter("endDate", endDate);
        } else if (startDate != null) {
            query.setParameter("startDate", startDate);
        }
        return query.getResultList();
    }


}
